package com.seven.z7.logviewer;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import com.seven.z7.logviewer.controls.Menu;
import com.seven.z7.logviewer.controls.TextDropTarget;
import com.seven.z7.logviewer.controls.panel.ColorJTextPane;
import com.seven.z7.logviewer.controls.panel.DDMSColouringAgent;
import com.seven.z7.logviewer.utilities.WindowUtilities;

/**
 * 
 * @author aprokofjev
 * 
 */
public class MainFrame implements ActionListener {

	public static final String FRAME_TITLE = "Z7 Log Viewer";
	public static final String FRAME_VERSION = "1.0.0";
	private static final Dimension FRAME_DIMENSION = new Dimension(800, 600);

	public static final String ACTION_OPEN = "Open File...";
	public static final String ACTION_EXIT = "Exit";
	public static final String ACTION_ABOUT = "About";
	public static final String ACTION_FIND = "Find...";
	public static final String ACTION_FIND_NEXT = "Find Next";
	public static final String ACTION_DROP = "Drop";

	private static final String PATH_XML_RES = "/xml";
	private static final String PATH_IMG_RES = "/img";

	private static final String PATH_MENU_FILE = PATH_XML_RES + "/menu.xml";
	private static final String PATH_STYLE_FILE = PATH_XML_RES + "/style.xml";
	private static final String PATH_ICON_FILE = PATH_IMG_RES + "/icon.png";

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		WindowUtilities.setNativeLookAndFeel();
		new MainFrame();
	}

	private JFrame mMainFrame;
	private ClosableTabbedPane mTabbedPane;

	public MainFrame() {
		initFrame();
		mMainFrame.setVisible(true);
	}

	private void initFrame() {
		mTabbedPane = new ClosableTabbedPane();

		new TextDropTarget(mTabbedPane, this);

		mMainFrame = WindowUtilities.createFrame(mTabbedPane, FRAME_DIMENSION, FRAME_TITLE);

		try {
			setAppIcon(getUri(PATH_ICON_FILE));
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}

		try {
			File menuFile = new File(getUri(PATH_MENU_FILE));
			setMenu(menuFile);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	}

	private URI getUri(String path) throws URISyntaxException, IOException {
		URL url = getClass().getResource(path);
		if (url != null) {
			return url.toURI();
		}
		throw new IOException("File " + path + " not found!");
	}

	private void setMenu(File file) throws URISyntaxException, ParserConfigurationException, IOException, SAXException {
		Menu menu = new Menu(this, file);
		mMainFrame.setJMenuBar(menu);
	}

	private void setAppIcon(URI uri) throws MalformedURLException {
		ImageIcon icon = new ImageIcon(uri.toURL());
		mMainFrame.setIconImage(icon.getImage());
	}

	@Override
	public void actionPerformed(ActionEvent ae) {
		try {
			if (ACTION_OPEN.equals(ae.getActionCommand())) {
				File file = openFile();
				if (file != null) {
					addTabPage(file);
				}
			} else if (ACTION_EXIT.equals(ae.getActionCommand())) {
				exit();
			} else if (ACTION_ABOUT.equals(ae.getActionCommand())) {
				WindowUtilities.showInfo(mMainFrame, "About", "Version: " + FRAME_VERSION);
			} else if (ACTION_DROP.equals(ae.getActionCommand())) {
				List<?> files = (List<?>) ae.getSource();
				for (Object file : files) {
					if (file instanceof File) {
						addTabPage((File) file);
					}
				}
			} else if (ACTION_FIND.equals(ae.getActionCommand())) {
				ShowFindDialog();
			} else if (ACTION_FIND_NEXT.equals(ae.getActionCommand())) {
				System.out.println("find next");
			}
		} catch (IOException e) {
			e.printStackTrace();
			WindowUtilities.showError(mMainFrame, "Error", e.toString());
		} catch (SAXException e) {
			e.printStackTrace();
			WindowUtilities.showError(mMainFrame, "Error", e.toString());
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			WindowUtilities.showError(mMainFrame, "Error", e.toString());
		} catch (URISyntaxException e) {
			e.printStackTrace();
			WindowUtilities.showError(mMainFrame, "Error", e.toString());
		}
	}

	private void ShowFindDialog() {
		// Dialog dialog = new FindMsbbox(mMainFrame);
		// dialog.setVisible(true);
	}

	private File openFile() {
		JFileChooser fc = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("Z7 Log", "log");
		fc.setFileFilter(filter);
		return fc.showOpenDialog(mMainFrame) == JFileChooser.APPROVE_OPTION ? fc.getSelectedFile() : null;
	}

	private void exit() {
		mMainFrame.setVisible(false);
		mMainFrame.dispose();
		System.exit(0);
	}

	private void addTabPage(File file) throws IOException, SAXException, ParserConfigurationException,
			URISyntaxException {
		FileInputStream is = new FileInputStream(file);
		InputStreamReader sr = new InputStreamReader(is);
		BufferedReader in = new BufferedReader(sr);

		URL url = getClass().getResource(PATH_STYLE_FILE);
		File style = new File(url.toURI());
		DDMSColouringAgent agent = new DDMSColouringAgent(style);
		ColorJTextPane tabPane = new ColorJTextPane(agent);

		mTabbedPane.addTab(file.getName(), new JScrollPane(tabPane));

		String line = null;
		while ((line = in.readLine()) != null) {
			tabPane.setText(line);
		}
	}
}
